﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using RimeAppDemo.DataProtocal;
using Rimelink.Data.Mqtt;
using RimeLoRaTool.LoraServer;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using zoyobar.shared.panzer;
using zoyobar.shared.panzer.web.ib;

namespace RimeAppDemo
{
    public partial class Form1 : Form
    {
        // 2021-0319 V1.1 从 chirpstack v3.11.0 开始使用 email，不使用 username，两者都带上，则可以兼容。
        // 2021-0421 V3.0 使用 SDK 发送组播消息
        // 2021-0610 V3.1 组播支持 mcKey_encrypted
        // 2021-0621 V3.2 支持 defaultclass A/C 配置，表示默认添加的设备的 CLASS 类型
        // 2022-0815 V3.3 支持 defaultjoin ABP/OTAA 配置，表示默认添加的设备的 JOIN 类型
        // 2023-0112 V3.4 NS Docker 方式下的 chirpstack-network-server:8000 尝试（localhost 失败后自动尝试）
        // 2023-0327 V3.5 主机端口支持在 主机后加:9999 方式指定别的端口。
        // 2023-0725 V4.0 向页面开放获取 应用列表 和 设置当前应用标识的方法，页面可以选择操作哪个应用
        public static string Version = "V4.0";
        public static Form1 Instance;
        private IEBrowser ie;
        public Form1()
        {
            Instance = this;
            InitializeComponent();
        }

        // Rime LoRa Data 客户端
        private Client client = null;
        private void Form1_Load(object sender, EventArgs e)
        {
            Text = ConfigurationManager.AppSettings["name"] + " " + Version;

            ie = new IEBrowser(this.webBrowser1);
            ie.IsNewWindowEnabled = true;
            ie.Scripting = new ScriptForWeb();

            this.webBrowser1.Navigate( Application.StartupPath + @"/Main.html");
            // this.webBrowser1.DocumentText = "Main.html"; // GetMainHtml(); 
        }

        /// <summary>
        /// 将数据格解析成 json
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        private JObject ParseData(byte[] data)
        {
            var result = ParseHelper.ParseData(data);
            return result;
        }

        private void DebugConsole(string info)
        {
            Invoke(new MethodInvoker(delegate
               {
                   try
                   {
                       ie.IEFlow.Wait(new UrlCondition("wait", @"", StringCompareMode.Contain), 1);
                       ie.InstallScript("function _HasReceiver(){ if(window.__receive) return true; return false; }", "runner");
                       if ("True".Equals(ie.InvokeScript("_HasReceiver").ToString()))
                       {
                           ie.InvokeScript("__receive", new object[] { info });
                       }
                   }
                   catch(Exception e)
                   {
                       Log(e.Message);
                   }
               }));
        }

        public void State(string state)
        {
            lblState.Text = state;
            if (state.Contains("成功"))
            {
                lblState.ForeColor = Color.Green;
            }
            else
            {
                lblState.ForeColor = Color.Black;
            }
        }

        private bool _AllowLoging = true;
        /// <summary>
        /// 日志输出
        /// </summary>
        /// <param name="info"></param>
        public void Log(string info)
        {
            if (!_AllowLoging) return;

            Invoke(new MethodInvoker(delegate
            {
                txtLog.AppendText(String.Format("{0} {1}\r\n\r\n", DateTime.Now.ToString("MM-dd HH:mm:ss"), info));
            }));
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (client != null)
            {
                client.End();
            }
            client = null; 
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            txtLog.Clear();
        }

        // 测试    
        private void test(object sender, EventArgs e)
        { 
            var context = new LoraServerContext();
            context.Host = "localhost";
            ILoraServerIOPiper piper = new LoraServerIOPiper(context);
            var vr = piper.Login("admin", "admin");
            Log(vr.Message);
            if (!vr.IsValid) return;
            context.Token = vr.Message;

            var olist = piper.GetOrganizationList(1, 0);
            Log("orgainzation count : " + olist.Count);
            if (olist.Count == 0) return;
            Log("First orgainzation : " + olist[0].displayName);
            context.OrganizationID = int.Parse(olist[0].id);

            var nlist = piper.GetNetworkServerList(1, 0);
            Log("netword server count : " + nlist.Count);
            if (nlist.Count == 0)
            {
                vr = piper.AddNetworkServer("localhost-hs", "localhost:8000");
                Log("add network server result : " + vr.Message);
                return;
            }
            context.NetworkServerID = int.Parse(nlist[0].id);
            Log("First netword server : " + nlist[0].name + " " + nlist[0].server);

            var slist = piper.GetServiceProfileList(1, 0, context.OrganizationID);
            Log("service profile count : " + slist.Count);
            if (slist.Count == 0)
            {
                vr = piper.AddServiceProfile("serviceprofile1", context.NetworkServerID, true, context.OrganizationID);
                Log("add service profile result : " + vr.Message);
                return;
            }
            context.ServiceProfileID = slist[0].id;
            Log("First service profile : " + slist[0].id + " " + slist[0].name);

            var glist = piper.GetGatewayProfileList(1, 0, context.NetworkServerID);
            Log("gateway profile count : " + glist.Count);
            if (glist.Count == 0)
            {
                vr = piper.AddGatewayProfile("gatewayprofile1", context.NetworkServerID, "80,81,82,83,84,85,86,87");
                Log("add gateway profile result : " + vr.Message);
                return;
            }
            context.GatewayProfileID = glist[0].id;
            Log("First gateway profile : " + glist[0].id + " " + glist[0].name);

            var dlist = piper.GetDeviceProfileList(20, 0, context.OrganizationID);
            Log("device profile count : " + dlist.Count);
            
            foreach (var dp in dlist)
            {
                DeviceProfile item = null;
                try
                {
                    item = piper.GetDeviceProfile(dp.id);
                }
                catch (Exception de)
                {
                    Log("device profile " + dp.id + " : " + de.Message);
                    continue;
                }
                if (item.supportsJoin)
                {
                    if (item.supportsClassC)
                    {
                        context.DeviceProfileOTAA_C = item.id;
                    }
                    else
                    {
                        context.DeviceProfileOTAA = item.id;
                    }
                }
                else
                {
                    if (item.supportsClassC)
                    {
                        context.DeviceProfileABP_C = item.id;
                    }
                    else
                    {
                        context.DeviceProfileABP = item.id;
                    }
                } 
                Log("device profile : " + dp.id + " " + dp.name + String.Format("regParamsRevision:{0}，macVersion:{1}, join:{2}, class c:{3}", item.regParamsRevision, item.macVersion, item.supportsJoin, item.supportsClassC));
            }
            if (String.IsNullOrEmpty(context.DeviceProfileABP))
            {
                vr = piper.AddDeviceProfile("deviceprofileABP", context.NetworkServerID, false, false, context.OrganizationID);
                Log("add device profile abp result : " + vr.Message);
                if (!vr.IsValid)
                {
                    return;
                }
                context.DeviceProfileABP = vr.Message;
            }
            if (String.IsNullOrEmpty(context.DeviceProfileABP_C))
            {
                vr = piper.AddDeviceProfile("deviceprofileABP_C", context.NetworkServerID, false, true, context.OrganizationID);
                Log("add device profile abp c result : " + vr.Message);
                if (!vr.IsValid)
                {
                    return;
                }
                context.DeviceProfileABP_C = vr.Message;
            }
            if (String.IsNullOrEmpty(context.DeviceProfileOTAA))
            {
                vr = piper.AddDeviceProfile("deviceprofileOTAA", context.NetworkServerID, true, false, context.OrganizationID);
                Log("add device profile otaa result : " + vr.Message);
                if (!vr.IsValid)
                {
                    return;
                }
                context.DeviceProfileOTAA = vr.Message;
            }
            if (String.IsNullOrEmpty(context.DeviceProfileOTAA_C))
            {
                vr = piper.AddDeviceProfile("deviceprofileOTAA_C", context.NetworkServerID, true, true, context.OrganizationID);
                Log("add device profile otaa c result : " + vr.Message);
                if (!vr.IsValid)
                {
                    return;
                }
                context.DeviceProfileOTAA_C = vr.Message;
            }
            // 增加应用
            var alist = piper.GetApplicationList(1, 0, context.OrganizationID);
            Log("application count : " + alist.Count);
            if (alist.Count == 0)
            {
                var app = piper.AddApplication("myapp", context.OrganizationID, context.ServiceProfileID, "my app");
                Log("add application : " + app.Message);
                return;
            }
            context.ApplicationID = int.Parse(alist[0].id);
            Log("First application : " + alist[0].id + " " + alist[0].name);

            // 增加网关
            vr = piper.AddGateway("1111111122222222", "test-gateway", "测试api添加", context.GatewayProfileID, context.NetworkServerID, context.OrganizationID);
            Log("add gateway 1111111122222222 result : " + vr.Message);

            var gcnt = piper.GetGatewayCnt(context.OrganizationID);
            Log("gateway count : " + gcnt);

            // 增加节点
            vr = piper.AddDevice(context.ApplicationID, "device-test1", "1212121215151516", context.DeviceProfileABP, "测试");
            Log("add device : " + vr.IsValid + " " + vr.Message);

            vr = piper.UpdateDeviceActivation("1212121215151516", "15151516", LoraServerContext.DEFAULT_APP_ENC_KEY, LoraServerContext.DEFAULT_APP_ENC_KEY);
            Log("device activation update : " + vr.Message);

            var dcnt = piper.GetDeviceCnt(context.ApplicationID);
            Log("device count : " + dcnt);
        }
    
        private void btnSetLog_Click(object sender, EventArgs e)
        {
            _AllowLoging = !_AllowLoging;

            // btnSetLog.Text = _AllowLoging ? "暂停日志" : "显示日志"; 
        }

        public void Navigate(string url)
        {
            this.webBrowser1.Navigate(url);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            System.Environment.Exit(0);
        }
    }

    
}
